﻿package gear.key {
	import flash.display.Stage;
	import flash.events.Event;
	import flash.events.KeyboardEvent;
	import flash.utils.Dictionary;

	/**
	 * 热键控制
	 * 
	 * @author  bright
	 * @version 20101015
	 */
	public class HotKey {
		public static const K_A : uint = 65;
		public static const K_D : uint = 68;
		public static const K_W : uint = 87;
		public static const K_S : uint = 83;
		public static const K_E : uint = 69;
		public static const K_Q : uint = 81;
		public static const K_Z : uint = 90;
		public static const K_X : uint = 88;
		public static const K_C : uint = 67;
		public static const K_1 : uint = 49;
		public static const K_2 : uint = 50;
		public static const K_3 : uint = 51;
		public static const K_4 : uint = 52;
		public static const K_5 : uint = 53;
		public static const K_6 : uint = 54;
		public static const K_7 : uint = 55;
		public static const K_8 : uint = 56;
		private var _owner : Stage;
		private var _active : Boolean;
		private var _filter : IHotKeyFliter;
		private var _dict : Dictionary;

		private function keyDownHandler(event : KeyboardEvent) : void {
			var keyCode : uint = _filter.convertKeyCode(event.keyCode);
			if (_filter.keyDownFliter(keyCode)) {
				return;
			}
			var keyData : HotKeyData = _dict[keyCode];
			if (keyData == null || !keyData.active) {
				return;
			}
			keyData.onKeyDown();
		}

		private function keyUpHandler(event : KeyboardEvent) : void {
			var keyCode : uint = _filter.convertKeyCode(event.keyCode);
			var keyData : HotKeyData = _dict[keyCode];
			if (keyData == null || !keyData.active ) {
				return;
			}
			keyData.onKeyUp();
		}

		private function deactivateHandler(event : Event) : void {
			for each (var keyData:HotKeyData in _dict) {
				keyData.onKeyUp();
			}
		}

		/**
		 * 构造函数
		 * 
		 * @param stage 舞台
		 * @param filter 键过滤接口
		 */
		public function HotKey(stage : Stage, filter : IHotKeyFliter) {
			_owner = stage;
			_filter = filter;
			_active = false;
			_dict = new Dictionary(false);
		}

		/**
		 * 重置键码定义
		 * 
		 * @param keyCode 键码
		 */
		public function reset(keyCode : uint) : void {
			var data : HotKeyData = _dict[keyCode];
			if (data == null) {
				return;
			}
			data.reset();
		}

		/**
		 * 设置激活状态
		 * 
		 * @param value 激活状态
		 */
		public function set active(value : Boolean) : void {
			if (_active == value) {
				return;
			}
			_active = value;
			if (_active) {
				_owner.addEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler);
				_owner.addEventListener(KeyboardEvent.KEY_UP, keyUpHandler);
				_owner.addEventListener(Event.DEACTIVATE, deactivateHandler);
			} else {
				_owner.removeEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler);
				_owner.removeEventListener(KeyboardEvent.KEY_UP, keyUpHandler);
				_owner.removeEventListener(Event.DEACTIVATE, deactivateHandler);
			}
		}

		/**
		 * 设置热键回调
		 * 
		 * @param keyCode 键码
		 * @param callback 回调函数
		 * @param mode 模式
		 */
		public function setHotKey(keyCode : uint, callback : Function, mode : int = 0) : void {
			if (callback == null) {
				delete _dict[keyCode];
			} else {
				_dict[keyCode] = new HotKeyData(keyCode, callback, mode);
			}
		}

		/**
		 * 热键是否按下
		 * 
		 * @param keyCode 键码
		 * @return 
		 */
		public function isKeyDown(keyCode : uint) : Boolean {
			var keyData : HotKeyData = _dict[keyCode];
			if (keyData == null) {
				return false;
			}
			return keyData.isKeyDown;
		}

		/**
		 * 设置指定键码的激活状态
		 * 
		 * @param keyCode 键码
		 * @param active 是否激活
		 */
		public function setActive(keyCode : uint, active : Boolean) : void {
			var keyData : HotKeyData = _dict[keyCode];
			if (keyData == null) {
				return;
			}
			keyData.active = active;
		}

		/**
		 * 获得指定键码的激活状态
		 * 
		 * @return 指定的激态
		 */
		public function getActive(keyCode : uint) : Boolean {
			var keyData : HotKeyData = _dict[keyCode];
			if (keyData == null) {
				return false;
			}
			return keyData.active;
		}
	}
}